package ourvod.jxta;

import java.io.File;
import java.io.IOException;

import Examples.Z_Tools_And_Others.Tools;

import net.jxta.discovery.DiscoveryService;
import net.jxta.exception.PeerGroupException;
import net.jxta.peergroup.PeerGroup;
import net.jxta.platform.NetworkManager;
import ourvod.util.PeerGroupUtil;

public class P2PSystem {

	private static final P2PSystem INSTANCE = new P2PSystem();

	private P2PSystem() {
	}

	public static P2PSystem getInstance() {
		return INSTANCE;
	}

	public static final int RDV_CONNECT_TRIES = 5;
	public static final int RDV_CONNECT_TIMEOUT = 2000;

	private NetworkManager manager;
	private PeerGroup netPeerGroup;
	private DiscoveryService discoveryService;

	private PeerGroup ourvodPeerGroup;

	public PeerGroup getOurvodPeerGroup() {
		return this.ourvodPeerGroup;
	}

	public boolean startJxta() {
		
		try {
			Tools.CheckForExistingConfigurationDeletion("P2P system", new File(".jxta"));
			manager = new NetworkManager(NetworkManager.ConfigMode.EDGE, PeerGroupUtil.GROUP_NAME, new File(".jxta").toURI());

			// TODO: network configuration
			// NetworkConfigurator config = manager.getConfigurator();
			// config.setTcpPort(9071);
			// config.addSeedRendezvous(URI.create("tcp://121.22.29.30:9701"));
			// config.addSeedRendezvous(URI.create("tcp://10.22.2.87:9701"));

			netPeerGroup = manager.startNetwork();
			discoveryService = netPeerGroup.getDiscoveryService();

		} catch (PeerGroupException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}

		// try to connect to a rendevous in NetPeergroup
		if (!netPeerGroup.getRendezVousService().isRendezVous()) {
			int count = 0;
			System.out.println("try to connect to Rendezvous in NetPeergroup...");
			while (!netPeerGroup.getRendezVousService().isConnectedToRendezVous()) {
				try {
					if (count == RDV_CONNECT_TRIES)
						break;
					count++;
					Thread.sleep(RDV_CONNECT_TIMEOUT);
				} catch (InterruptedException ex) {
					// do nothing
				}
			}

			boolean connected = netPeerGroup.getRendezVousService().isConnectedToRendezVous();

			if (!connected) {
				System.out.println("can't find any Rendezvous in NetPeergroup");
			}
		}

        // Discover (or create) and join the ourvod peergroup
		ourvodPeerGroup = PeerGroupUtil.discoverOrCreateAndJoinPeerGroup(netPeerGroup, discoveryService,"ourvod");
		if (ourvodPeerGroup == null) {
			// failed to join ourvod peergroup
			System.err.println("failed to join ourvod peergroup");
			return false;
		}

		// try to connect to a rendevous in ourvod
		if (!ourvodPeerGroup.getRendezVousService().isRendezVous()) {
			int count = 0;
			while (!ourvodPeerGroup.getRendezVousService().isConnectedToRendezVous()) {
				try {
					if (count == RDV_CONNECT_TRIES)
						break;
					count++;
					Thread.sleep(RDV_CONNECT_TIMEOUT);
				} catch (InterruptedException ex) {
				}
			}
			System.out.println("is connected to ourvod Rendezvous: " + ourvodPeerGroup.getRendezVousService().isConnectedToRendezVous());
		}

		return true;
	}

	public void stopJxta() {
		manager.stopNetwork();

		System.exit(0);
	}
}
